#include "GrammarErrorHandlers.h"
#include "TokenManager.h"

GrammarErrorHandlers::GrammarErrorHandlers():
    _lastSuiteStartCol(-1),
    _errorCount(0)
{
}

void GrammarErrorHandlers::markLastAsSuiteStart()
{
    TokenPtr currentToken(getCurrentToken());
    _lastSuiteStartCol = currentToken->beginColumn;
}

void GrammarErrorHandlers::handleRParensNearButNotCurrent(const ParseException& ex)
{
    qDebug() << "Three";
    /*addAndReport("Handle parens near but not current");
    Token* t = getCurrentToken();

    AbstractTokenManager* tokenManager = getTokenManager();
    int rparenId = tokenManager->getRparenId();
    while (t != NULL && t->kind != rparenId) {
        t = t->next;
    }
    if(t != NULL && t->kind == rparenId){
        //found it
        setCurrentToken(t);
    }*/
}

void GrammarErrorHandlers::addAndReport(const ParseException& ex, const QString & msg)
{
    qDebug() << "Error:" << msg << ex.message;
    /*if(DEBUG_SHOW_PARSE_ERRORS){
        //System.err.println("\n\n\n\n\n---------------------------------\n"+msg);
        //e.printStackTrace();
    }
    addParseError(msg);
    parseExceptions ++;
    if(parseExceptions > 100){ //too many errors in the file... just stop trying to fix it (we could be recursing too)
        throw "too many errors in the file...";
    }*/
}

void GrammarErrorHandlers::handleNoNewline(const ParseException& ex)
{
    addAndReport(ex, "Handle no newline");
}

void GrammarErrorHandlers::handleErrorInImport(const ParseException& ex)
{
    addAndReport(ex, "Handle error in import");
}

void GrammarErrorHandlers::handleErrorInCompountStmt(const ParseException& ex)
{
    addAndReport(ex, "Handle error in compount stmt");
}

void GrammarErrorHandlers::handleNoEof(const ParseException& ex)
{
    addAndReport(ex, "Handle no EOF");
}

void GrammarErrorHandlers::handleErrorInIndent(const ParseException& ex)
{
    addAndReport(ex, "Handle no indent");

    /*TokensIterator iterTokens = this.getTokensIterator(getCurrentToken(), 3, false);
    iterTokens.next(); //discard the curr
    if(!iterTokens.hasNext()){
        throw new EmptySuiteException();
    }
    Token nextToken = iterTokens.next();
    if(nextToken.beginColumn <= lastSuiteStartCol){
        throw new EmptySuiteException();
    }*/
}

void GrammarErrorHandlers::handleErrorInStmt(const ParseException& ex)
{
    addAndReport(ex, "Handle error in stmt");
}

void GrammarErrorHandlers::handleErrorInDedent(const ParseException& ex)
{
    addAndReport(ex, "Handle dedent");
    //lot's of tokens, but we'll bail out on an indent, so, that's OK.
    /*AbstractTokenManager tokenManager = getTokenManager();
    int indentId = tokenManager.getIndentId();
    int dedentId = tokenManager.getDedentId();


    int level = 0;

    //lot's of tokens, but we'll bail out on an indent, so, that's OK.
    TokensIterator iterTokens = this.getTokensIterator(getCurrentToken(), 50, false);
    while (iterTokens.hasNext()) {
        Token next = iterTokens.next();
        if(level == 0){
            //we can only do it if we're in the same level we started.
            if(next.kind == dedentId){
                setCurrentToken(next);
                break;
            }
        }
        if(next.kind == indentId){
            level += 1;
        }else if(next.kind == dedentId){
            level -= 1;
        }
    }*/
}

void GrammarErrorHandlers::handleNoNewlineInSuiteFound()
{
    addAndReport(ParseException("No new line found.", getCurrentToken()), "Handle no new line in suite");
}

void GrammarErrorHandlers::handleNoSuiteMatch(const ParseException& ex)
{
    addAndReport(ex, "Handle no suite match");
}

void GrammarErrorHandlers::handleNoValInDict(const ParseException& ex)
{
    addAndReport(ex, "No value for dict key");
}

TokenPtr GrammarErrorHandlers::handleErrorInName(const ParseException& ex)
{
    addAndReport(ex, "Handle name");
    TokenPtr currentToken = getCurrentToken();

    return getTokenManager()->createFrom(currentToken, /*JJTNAME*/125, "!<MissingName>!");
}

void GrammarErrorHandlers::handleUnexpectedToken(int /*expectedKind*/, const QString& expectedToken, const TokenPtr& actual)
{
    qDebug() << "ONe";
}

void GrammarErrorHandlers::handleParseError(const TokenPtr&/*last*/, const TokenPtr& unexpected, const QString& production)
{
    qDebug() << "Two";
    //addAndReport(generateParseException(), "Parse error");
}

void GrammarErrorHandlers::handleParseError(const ParseException& ex)
{
    addAndReport(ex, "Parse error");
}
